package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.heima.api.article.IArticleClient;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.tess4j.Tess4jClient;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmSensitiveMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.WmNewsAutoScanService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional
public class WmNewsAutoScanServiceImpl implements WmNewsAutoScanService {
	@Autowired
	private WmNewsMapper wmNewsMapper;

	/**
	 * 自媒体文章审核
	 *
	 * @param id 自媒体文章id
	 */
	@Override
	public void autoScanWmNews(Integer id) {
		//1.查询自媒体文章
		WmNews wmNews = wmNewsMapper.selectById(id);
		//当文章不存在时，终止
		if (wmNews == null) {
			throw new RuntimeException("WmNewsAutoScanServiceImpl-文章不存在");
		}
		if (wmNews.getStatus().equals(WmNews.Status.SUBMIT.getCode())) {
			//从内容中提纯文本内容和图片
			Map<String, Object> textAndImages = handlerTextAndImages(wmNews);
			//自管理敏感词审核
			boolean sensitiveScanFlag = handlerSensitiveScan(wmNews, (String) textAndImages.get("content"));
			if (!sensitiveScanFlag) {
				return;
			}
			//审核文本内容 阿里云接口
			boolean isTextScan = handlerTextScan((String) textAndImages.get("content"), wmNews);
			if (!isTextScan) {
				return;
			}
			//审核图片 阿里云接口
			boolean isImageScan = handlerImageScan((List<String>) textAndImages.get("images"), wmNews);
			if (!isImageScan) {
				return;
			}
			//调用feign接口保存三剑客
			Long articleId = saveAppArticle(wmNews);

			//修改wm_news表状态
			wmNews.setArticleId(articleId);
			updateWmNews(wmNews, WmNews.Status.PUBLISHED.getCode(), "发布审核成功");
		}
	}

	@Autowired(required = false)
	private WmSensitiveMapper wmSensitiveMapper;

	/**
	 * 方法五，自管理词过滤
	 *
	 * @param wmNews
	 * @param content
	 * @return
	 */
	private boolean handlerSensitiveScan(WmNews wmNews, String content) {
		boolean flag = true;
		//查询敏感词的集合
		List<WmSensitive> wmSensitive = wmSensitiveMapper.selectList(null);
		List<String> wmSensitiveList = wmSensitive.stream().map(WmSensitive::getSensitives).collect(Collectors.toList());
		//初始化敏感词库
		SensitiveWordUtil.initMap(wmSensitiveList);
		//进行匹配，查看是否有命中
		Map<String, Integer> stringIntegerMap = SensitiveWordUtil.matchWords(content);
		if (stringIntegerMap.size() > 0) {
			updateWmNews(wmNews, WmNews.Status.FAIL.getCode(), "文本中含有自定义敏感词汇");
			flag = false;
		}
		return flag;
	}

	@Autowired
	private IArticleClient iArticleClient;
	@Autowired
	private WmChannelMapper wmChannelMapper;
	@Autowired
	private WmUserMapper wmUserMapper;
	@Autowired
	private IArticleClient articleClient;

	/**
	 * 方法四 保存三剑客
	 *
	 * @param wmNews
	 * @return
	 */
	private Long saveAppArticle(WmNews wmNews) {
		ArticleDto dto = new ArticleDto();
		//拷贝属性
		BeanUtils.copyProperties(wmNews, dto);
		//文章布局
		dto.setLayout(wmNews.getType());
		//频道
		WmChannel wmChannel = wmChannelMapper.selectById(wmNews.getChannelId());
		if (wmChannel != null) {
			dto.setChannelName(wmChannel.getName());
		}
		//作者
		dto.setAuthorId(wmNews.getUserId().longValue());
		WmUser wmUser = wmUserMapper.selectById(wmNews.getUserId());
		if (wmUser != null) {
			dto.setAuthorName(wmUser.getName());
		}
		//点赞，收藏，阅读，评论数量
		dto.setLikes(0);
		dto.setViews(0);
		dto.setCollection(0);
		dto.setComment(0);
		//设置文章id
		if (wmNews.getArticleId() != null) {
			dto.setId(wmNews.getArticleId());
		}
		//设置时间
		dto.setCreatedTime(new Date());

		//远程保存feign接口
		ResponseResult result = articleClient.save(dto);
		if (result.getCode() != 200) {
			return null;
		}
		return (Long) result.getData();
	}

	@Autowired
	private FileStorageService fileStorageService;
	@Autowired(required = false)
	private GreenImageScan greenImageScan;
	@Autowired
	private Tess4jClient tess4jClient;

	/**
	 * 方法三 审核图片
	 *
	 * @param images
	 * @param wmNews
	 * @return
	 */
	private boolean handlerImageScan(List<String> images, WmNews wmNews) {
		boolean flag = true;

		try {
			List<byte[]> imageByteList = new ArrayList<>();
			//下载图片
			if (images != null && images.size() > 0) {
				for (String imageUrl : images) {
					//下载图片
					byte[] bytes = fileStorageService.downLoadFile(imageUrl);

					//图片OCR审核
					InputStream in = new ByteArrayInputStream(bytes);
					BufferedImage image = ImageIO.read(in);
					String resultText = tess4jClient.doOCR(image);
					//执行自管理敏感词审核
					Boolean sensitiveScanFlag = handlerSensitiveScan(wmNews, resultText);
					if (!sensitiveScanFlag) {
						return false;
					}

					imageByteList.add(bytes);
				}
			}
			//审核图片
			Map map = greenImageScan.imageScan(imageByteList);
			if (map != null) {
				//审核失败
				if (map.get("suggestion").equals("block")) {
					flag = false;
					updateWmNews(wmNews, WmNews.Status.FAIL.getCode(), "当前图片中存在违规内容");
				}
				//不确定信息交给人工审核
				if (map.get(":suggestion").equals("review")) {
					flag = false;
					updateWmNews(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "当前图片中存在不确定内容，已提交人工审核");
				}
			}
		} catch (Exception e) {
			flag = false;
			e.printStackTrace();
		}
		return flag;
	}

	@Autowired(required = false)
	private GreenTextScan greenTextScan;

	/**
	 * 方法二 审核文本内容
	 *
	 * @param content
	 * @param wmNews
	 * @return
	 */
	private boolean handlerTextScan(String content, WmNews wmNews) {
		boolean flag = true;
		if ((wmNews.getTitle() + "-" + content).length() == 0) {
			return flag;
		}
		try {
			Map map = greenTextScan.greeTextScan(wmNews.getTitle() + "-" + content);
			if (map != null) {
				//审核失败
				if (map.get("suggestion").equals("block")) {
					flag = false;
					updateWmNews(wmNews, (short) 2, "当前文章存在违规内容");
				}
				//不确定的内容需要人工审核
				if (map.get("suggestion").equals("review")) {
					flag = false;
					updateWmNews(wmNews, (short) 3, "当前文章中存在不确定内容");
				}
			}
		} catch (Exception e) {
			flag = false;
			e.printStackTrace();
		}
		return flag;
	}

	/**
	 * 修改文章内容
	 *
	 * @param wmNews
	 * @param status
	 * @param reason
	 */
	private void updateWmNews(WmNews wmNews, short status, String reason) {
		wmNews.setStatus(status);
		wmNews.setReason(reason);
		wmNewsMapper.updateById(wmNews);
	}

	/**
	 * 方法一
	 * 1.从自媒体文章内容中提取文本和图片
	 * 2.提取文章的封面图片
	 *
	 * @param wmNews
	 * @return
	 */
	private Map<String, Object> handlerTextAndImages(WmNews wmNews) {
		//存储纯文本内容
		StringBuilder stringBuilder = new StringBuilder();
		List<String> images = new ArrayList<>();
		//1.从自媒体文章内容中提取文本和图片
		if (StringUtils.isNoneBlank(wmNews.getContent())) {
			List<Map> maps = JSONArray.parseArray(wmNews.getContent(), Map.class);
			for (Map map : maps) {
				if (map.get("type").equals("text")) {
					stringBuilder.append(map.get("value"));
				}
				if (map.get("type").equals("image")) {
					images.add((String) map.get("value"));
				}
			}
		}
		//2.提取文章的封面和图片
		if (StringUtils.isNoneBlank(wmNews.getImages())) {
			String[] split = wmNews.getImages().split(",");
			images.addAll(Arrays.asList(split));
		}
		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("content", stringBuilder.toString());
		resultMap.put("image", images);
		return resultMap;
	}
}
